namespace Fftw
{
    using System;
    using System.Runtime.InteropServices;
    
    public abstract class Plan
    {
        public static uint FFTW_ESTIMATE = 1U << 6;
        public static uint FFTW_MEASURE = 0U;
        
        protected IntPtr raw;
        protected Direction direction;
        protected uint flags;
        protected Complex[] in_data;
        protected Complex[] out_data;
        protected double[] in_data_real;
        protected double[] out_data_real;
        
        [DllImport ("libfftw3")]
        protected static extern void fftw_execute(IntPtr plan);
        
        public void Execute()
        {
            fftw_execute(raw);
        }
        
        protected abstract void CreatePlan();
        
        public Direction Direction
        {
            get { return direction; }
            set
            {
                direction = value;
                CreatePlan();
            }
        }
        
        public uint Flags
        {
            get { return flags; }
            set
            {
                flags = value;
                CreatePlan();
            }
        }
        
        public Complex[] InputData
        {
            get { return in_data; }
            set
            {
                in_data = value;
                CreatePlan();
            }
        }
        
        public double[] InputDataReal
        {
            get { return in_data_real; }
            set
            {
                in_data_real = value;
                CreatePlan();
            }
        }
        
        public Complex[] OutputData
        {
            get { return out_data; }
        }
        
        public double[] OutputDataReal
        {
            get { return out_data_real; }
        }
    }
}
